home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / plan / src / notifier.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  8KB  |  338 lines

  1. /*
  2.  * Notify program. Pops up a green, yellow, or red menu with some text
  3.  * in it. A title can be specified, default is "Notify". The text is
  4.  * read from the argument file name, or from standard input.
  5.  *
  6.  * This program is intended to be used by the pland daemon. It must
  7.  * reside in the same directory as pland; pland looks at its own path
  8.  * in argv[0] to locate notifier.
  9.  *
  10.  * Author: thomas@bitrot.in-berlin.de (Thomas Driemeyer)
  11.  */
  12.  
  13. #ifndef MIPS
  14. #include <stdlib.h>
  15. #endif
  16. #include <stdio.h>
  17. #ifndef VARARGS
  18. #include <stdarg.h>
  19. #endif
  20. #include <time.h>
  21. #include <Xm/Xm.h>
  22. #include <X11/StringDefs.h>
  23. #include "notifier.h"
  24. #include "version.h"
  25. #include "bm_noticon.h"
  26.  
  27. #if defined(XlibSpecificationRelease) && defined(sgi)
  28. #include <X11/Xmu/Editres.h>
  29. #define EDITRES
  30. #endif
  31. #ifndef _XEditResCheckMessages
  32. #undef  EDITRES
  33. #endif
  34.  
  35. #ifdef USERAND
  36. #define random rand
  37. #define srandom srand
  38. #endif
  39.  
  40. static void init_colors(), readfile(), usage();
  41. #ifdef MIPS
  42. extern char *malloc(), *realloc();
  43. #endif
  44.  
  45. Display            *display;        /* common server */
  46. GC            gc;            /* common graphics context */
  47. char            *progname;        /* argv[0] */
  48. Pixel            color[NCOLS];        /* colors: COL_* */
  49. Pixel            bkcolor = COL_RED;    /* background color (COL_*) */
  50. XtAppContext        app;            /* application handle */
  51. static Widget        toplevel;        /* widget tree */
  52.  
  53.  
  54. static String fallbacks[] = {
  55.     "*background:        #a0a0a0",
  56.     "*colStd:        #202020",
  57.     "*colRedAlert:        #ff0000",
  58.     "*colYellowAlert:    #c0a000",
  59.     "*colGreenAlert:     #20a020",
  60. #ifndef sgi
  61.     "*fontList:        -*-helvetica-*-r-*-*-17-*",
  62. #else
  63.     "*fontList:        -b&h-*-medium-r-*-*-17-*",
  64. #endif
  65.     "*title.fontList:    -*-times-*-*-*-*-34-*",
  66. #ifndef sgi
  67.     "*message.fontList:    -*-new century schoolbook-*-r-*-*-17-*",
  68. #else
  69.     "*message.fontList:    -*-palatino-*-r-*-*-17-*",
  70. #endif
  71. #ifdef DESKTOP
  72.     "*sgiMode:        True",
  73.     "*useSchemes:        True",
  74. #endif
  75.     NULL
  76. };
  77.  
  78.  
  79. /*
  80.  * initialize everything and create the main calendar window
  81.  */
  82.  
  83. main(argc, argv)
  84.     int            argc;
  85.     char            *argv[];
  86. {
  87.     Pixmap            icon;
  88.     int            n, i;
  89.     String            *p;
  90.     char            *msg = 0;    /* points to ascii message */
  91.     char            *title = "Notifier";
  92.     char            *icontitle = "Notify";
  93.     long            timeout = 0;
  94.     char            geometry[40];
  95.  
  96.     if ((progname = strrchr(argv[0], '/')) && progname[1])
  97.         progname++;
  98.     else
  99.         progname = argv[0];
  100.     srandom(time((void *)0));
  101.     sprintf(geometry, "*geometry: +%d+%d",    random()*16&240,
  102.                         random()*16&240);
  103.     fallbacks[0] = geometry;
  104.     toplevel = XtAppInitialize(&app, title, NULL, 0,
  105. #        ifndef XlibSpecificationRelease
  106.                 (Cardinal *)&argc, argv,
  107. #        else
  108.                 /* X11R5 introduced XlibSpecificationRelease
  109.                    and made cast unnecessary */
  110.                 &argc, argv,
  111. #        endif
  112.                 fallbacks, NULL, 0);
  113. #    ifdef EDITRES
  114.     XtAddEventHandler(toplevel, (EventMask)0, TRUE, 
  115.                 _XEditResCheckMessages, NULL);
  116. #    endif
  117.     display = XtDisplay(toplevel);
  118.     gc = XCreateGC(display, DefaultRootWindow(display), 0, 0);
  119.     init_colors();
  120.     if (icon = XCreatePixmapFromBitmapData(display,
  121.                 DefaultRootWindow(display),
  122.                 icon_bits, icon_width, icon_height,
  123.                 WhitePixelOfScreen(XtScreen(toplevel)),
  124.                 BlackPixelOfScreen(XtScreen(toplevel)),
  125.                 DefaultDepth(display, 0)))
  126.  
  127.         XtVaSetValues(toplevel, XmNiconPixmap, icon, NULL);
  128.  
  129.     for (n=1; n < argc; n++)
  130.         if (*argv[n] == '-')
  131.             for (i=1; i && argv[n][i]; i++)
  132.                 switch(argv[n][i]) {
  133.                   case 'd':
  134.                     for (p=fallbacks; *p; p++)
  135.                         printf("%s%s\n", progname, *p);
  136.                     fflush(stdout);
  137.                     exit(0);
  138.                   case 'v':
  139.                     fprintf(stderr, "%s: %s %s\n",
  140.                         progname, VERSION, PATCHLEVEL);
  141.                     exit(0);
  142.                   case 'e':
  143.                     timeout = atol(&argv[n][i+1]);
  144.                     i = -1;
  145.                     break;
  146.                   case 't':
  147.                     title = &argv[n][i+1];
  148.                     i = -1;
  149.                     break;
  150.                   case 'i':
  151.                     icontitle = &argv[n][i+1];
  152.                     i = -1;
  153.                     break;
  154.                   case '1':
  155.                     bkcolor = COL_GREEN;
  156.                     break;
  157.                   case '2':
  158.                     bkcolor = COL_YELLOW;
  159.                     break;
  160.                   case '3':
  161.                     bkcolor = COL_RED;
  162.                     break;
  163.                   default:
  164.                     usage();
  165.                 }
  166.         else {
  167.             FILE *fp;
  168.             if (msg)
  169.                 usage();
  170.             if (!(fp = fopen(argv[n], "r"))) {
  171.                 fprintf(stderr, "%s: ", progname);
  172.                 perror(argv[n]);
  173.                 exit(1);
  174.             }
  175.             readfile(&msg, fp);
  176.             fclose(fp);
  177.         }
  178.     if (!msg)
  179.         readfile(&msg, stdin);
  180.  
  181.     XtVaSetValues(toplevel, XmNiconName, icontitle, NULL);
  182.     create_widgets(toplevel, title, msg);
  183.     XtRealizeWidget(toplevel);
  184.     XBell(display, 0);
  185.     XBell(display, 0);
  186.     if (timeout)
  187.         (void)XtAppAddTimeOut(app, timeout*60*1000,
  188.                         (XtTimerCallbackProc)exit, 0);
  189.     XtAppMainLoop(app);
  190.     return(0);
  191. }
  192.  
  193.  
  194. /*
  195.  * whenever something goes seriously wrong, this routine is called. It makes
  196.  * code easier to read. fatal() never returns. This may fail horribly if
  197.  * VARARGS is defined, but at least it's going to do *something*.
  198.  */
  199.  
  200. #ifndef VARARGS
  201. /*VARARGS*/
  202. fatal(char *fmt, ...)
  203. {
  204.     va_list            parm;
  205.  
  206.     va_start(parm, fmt);
  207.     fprintf(stderr, "%s: ", progname);
  208.     vfprintf(stderr, fmt, parm);
  209.     va_end(parm);
  210.     putc('\n', stderr);
  211.     exit(1);
  212. }
  213.  
  214. #else
  215. /*VARARGS*/
  216. fatal(fmt, a, b, c, d)
  217.     char    *fmt;
  218.     int    a, b, c, d;
  219. {
  220.     fprintf(stderr, fmt, a, b, c, d);
  221.     putc('\n', stderr);
  222.     exit(1);
  223. }
  224. #endif
  225.  
  226.  
  227. /*
  228.  * read the message to be displayed in the window from a file (or stdin).
  229.  * Allocate enough storage.
  230.  * This routine avoids feof() because it seems to be broken on some Unix PCs.
  231.  */
  232.  
  233. static void readfile(msg, fp)
  234.     char            **msg;
  235.     FILE            *fp;
  236. {
  237.     long            size = 4098;    /* msg size, two more for \0 */
  238.     long            nread = 0;    /* how many read so far */
  239.     int            ncs;        /* how many added this time */
  240.  
  241.     if (!(*msg = malloc(size)))
  242.         fatal("can't malloc %d bytes for message", size);
  243.     for (;;) {
  244.         ncs = fread(*msg + nread, 1, 4096, fp);
  245.         (*msg)[nread += ncs] = 0;
  246.         if (ncs < 4096)
  247.             break;
  248.         if (!(*msg = realloc(*msg, size += 4096)))
  249.             fatal("can't realloc %d bytes for message", size);
  250.     }
  251. }
  252.  
  253.  
  254. /*
  255.  * usage information
  256.  */
  257.  
  258. static void usage()
  259. {
  260.     fprintf(stderr,
  261.         "Usage: %s [options] [file]\nOptions:\n%s%s%s%s%s%s%s%s%s",
  262.             progname,
  263.             "\t-h\t\tprint this help text\n",
  264.             "\t-d\t\tdump fallback app-defaults and exit\n",
  265.             "\t-tstring\tset title string (quote blanks)\n",
  266.             "\t-istring\tset icon title string (quote blanks)\n",
  267.             "\t-v\t\tprint version string\n",
  268.             "\t-eN\t\texpire after N minutes\n",
  269.             "\t-1\t\tprint green window\n",
  270.             "\t-2\t\tprint yellow window\n",
  271.             "\t-3\t\tprint red window\n");
  272.     exit(1);
  273. }
  274.  
  275.  
  276. /*
  277.  * read real application resources
  278.  */
  279.  
  280. static char *string_resource(res_name, res_class_name)
  281.     char        *res_name;
  282.     char        *res_class_name;
  283. {
  284.     char        *res;
  285.     XtResource    res_list[1];
  286.  
  287.     res_list->resource_name   = res_name;
  288.     res_list->resource_class  = res_class_name;
  289.     res_list->resource_type   = XtRString;
  290.     res_list->resource_size   = sizeof(XtRString);
  291.     res_list->resource_offset = 0;
  292.     res_list->default_type    = XtRString;
  293.     res_list->default_addr    = NULL;
  294.  
  295.     XtGetApplicationResources(toplevel, &res, res_list, 1, NULL, 0);
  296.     return(res);
  297. }
  298.  
  299.  
  300. /*
  301.  * determine all colors, and allocate them.
  302.  */
  303.  
  304. static void init_colors()
  305. {
  306.     Screen            *screen = DefaultScreenOfDisplay(display);
  307.     Colormap        cmap;
  308.     XColor            rgb;
  309.     int            i, d;
  310.     char            *c, *n, class_name[256];
  311.  
  312.     cmap = DefaultColormap(display, DefaultScreen(display));
  313.     for (i=0; i < NCOLS; i++) {
  314.         switch (i) {
  315.           default:
  316.           case COL_STD:        n = "colStd";        d = 1;    break;
  317.           case COL_RED:        n = "colRedAlert";    d = 0;    break;
  318.           case COL_YELLOW:    n = "colYellowAlert";    d = 0;    break;
  319.           case COL_GREEN:    n = "colGreenAlert";    d = 0;    break;
  320.         }
  321.         strcpy(class_name, n);
  322.         class_name[0] &= ~('a'^'A');
  323.         c = string_resource(n, class_name);
  324.         if (!XParseColor(display, cmap, c, &rgb))
  325.             fprintf(stderr, "%s: unknown color \"%s\" (%s)\n",
  326.                             progname, c, n);
  327.         else if (!XAllocColor(display, cmap, &rgb))
  328.             fprintf(stderr, "%s: can't alloc color \"%s\" (%s)\n",
  329.                             progname, c, n);
  330.         else {
  331.             color[i] = rgb.pixel;
  332.             continue;
  333.         }
  334.         color[i] = d ? BlackPixelOfScreen(screen)
  335.                  : WhitePixelOfScreen(screen);
  336.     }
  337. }
  338.